#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
商户申请单操作相关接口调用示例
包括：申请单查询、申请单作废
"""

import os
import sys
import logging

# 添加项目根目录到Python路径，确保能够导入jlpay包
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from jlpay.base.config import OrgConfig
from jlpay.services.openmerch.register.merchant_service import MerchantService
from jlpay.model.openmerch.register.merchant import (
    MerchantOrderQueryRequest,
    MerchantOrderCancelRequest
)
from jlpay.utils.log_config import configure_rotating_file_logging

# =================== 常量定义 =====================
# 审核状态常量
AUDIT_STATUS_PENDING = "00"  # 待审核
AUDIT_STATUS_APPROVED = "01"  # 审核通过
AUDIT_STATUS_PROCESSING = "02"  # 审核中
AUDIT_STATUS_CANCELLED = "03"  # 申请单已作废
AUDIT_STATUS_REJECTED = "09"  # 审核驳回

# 签约状态常量
SIGN_STATUS_UNSIGNED = "00"  # 未签约
SIGN_STATUS_SIGNED = "01"  # 已签约
SIGN_STATUS_SIGNING = "02"  # 签约中
SIGN_STATUS_SIGN_FAILED = "09"  # 签约失败

# 功能开通状态常量
FUNCTION_SUCCESS = "01"  # 成功
FUNCTION_PROCESSING = "02"  # 处理中
FUNCTION_FAILED = "09"  # 失败

# 日志配置常量
LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(funcName)s() - %(message)s'
MAX_LOG_SIZE = 10 * 1024 * 1024  # 10MB
MAX_BACKUP_COUNT = 10

# =================== 日志配置 =====================
# 配置日志系统，使用滚动文件处理器
log_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "logs")
root_logger = configure_rotating_file_logging(
    level=logging.INFO,
    log_dir=log_dir,
    log_name_prefix="jlpay",
    log_format=LOG_FORMAT,
    max_bytes=MAX_LOG_SIZE,
    backup_count=MAX_BACKUP_COUNT,
    propagate=True,
    module_levels={
        'jlpay.http': logging.DEBUG ,
        'jlpay.service': logging.DEBUG,
        'examples': logging.DEBUG
    }
)

# 获取示例程序的logger实例
logger = logging.getLogger("examples.merchant_order")
logger.setLevel(logging.INFO)

# =================== 密钥配置 =====================
# SM2公私钥
sm2_public_key_pem = """-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEJJhFmjeMRp9GwShxtWunv6Wny//m
Dg2pcnu0llDQvIYo5O3R+al39NekciZ0BIrT21Y/QJrXgJIoyBr6STml6g==
-----END PUBLIC KEY-----"""

sm2_private_key_pem = """-----BEGIN EC PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgHqOp471SMDsQml2G
2ErpZPLD2X7rbMqa6P1O9Zqlhe+gCgYIKoEcz1UBgi2hRANCAAQkmEWaN4xGn0bB
KHG1a6e/pafL/+YODalye7SWUNC8hijk7dH5qXf016RyJnQEitPbVj9AmteAkijI
GvpJOaXq
-----END EC PRIVATE KEY-----"""

# 嘉联支付平台公钥
jlpay_pub_key_pem = """-----BEGIN PUBLIC KEY-----
MIIBMzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////v//////////
//////////8AAAAA//////////8wRAQg/////v////////////////////8AAAAA
//////////wEICjp+p6dn140TVqeS89lCafzl4n1FauPkt28vUFNlA6TBEEEMsSu
LB8ZgRlfmQRGajnJlI/jC7/yZgvhcVpFiTNMdMe8Nzai9PZ3nFm9zuNraSFT0KmH
fMYqR0AC3zLlITnwoAIhAP////7///////////////9yA99rIcYFK1O79Ak51UEj
AgEBA0IABKZ3VWwH0Aw9xvOWXb+xM2gXyApWEAZLFy8UyIigp3ehOTwPJ693njrg
NavTLdzAtFBqXRreivlwBTIFy8iRgn8=
-----END PUBLIC KEY-----"""

# =================== 工具函数 =====================
def create_config():
    """创建配置对象"""
    config = OrgConfig.builder() \
        .app_id("1vzougr30f9vcw") \
        .url("https://openapi-uat.jlpay.com") \
        .org_pri_key(sm2_private_key_pem) \
        .org_pub_key(sm2_public_key_pem) \
        .jlpay_pub_key(jlpay_pub_key_pem) \
        .auto_encrypt(True) \
        .crypto_alg("SM2WithSM4") \
        .auto_decrypt(True) \
        .build()
    return config

def send_request_and_handle_response(service, request, operation_name):
    """发送请求并处理响应"""
    try:
        # 根据操作类型调用不同的服务方法
        if isinstance(request, MerchantOrderQueryRequest):
            response = service.merchant_order_query(request)
        elif isinstance(request, MerchantOrderCancelRequest):
            response = service.merchant_order_cancel(request)
        else:
            logger.error(f"不支持的请求类型: {type(request)}")
            return None
        
        if response.is_success():
            logger.info(f"{operation_name}成功！")
            return response
        else:
            logger.error(f"{operation_name}失败: {response.ret_code} - {response.ret_msg}")
            return None
            
    except Exception as e:
        logger.error(f"请求异常: {str(e)}")
        return None

# =================== 示例函数 =====================
def merchant_order_query_demo(apply_id):
    """
    申请单查询示例
    
    Args:
        apply_id: 申请单编号
    """
    logger.info(f"开始执行申请单查询示例，申请单号: {apply_id}")
    
    # 创建配置对象和商户服务
    config = create_config()
    merchant_service = MerchantService(config)
    
    # 创建申请单查询请求
    request = MerchantOrderQueryRequest()
    request.set_apply_id(apply_id)
    
    # 发送请求
    response = send_request_and_handle_response(merchant_service, request, "申请单查询")
    
    # 处理响应
    if response and response.is_success():
        logger.info(f"申请单查询成功！")
        logger.info(f"响应报文：{response.to_dict()}")
    else:
        logger.error("申请单查询失败")
        if response:
            logger.error(f"响应报文：{response.to_dict()}")
    
    logger.info("申请单查询示例执行完毕")
    return response


def merchant_order_cancel_demo(apply_id):
    """
    申请单作废示例
    
    Args:
        apply_id: 申请单编号
    """
    logger.info(f"开始执行申请单作废示例，申请单号: {apply_id}")
    
    # 创建配置对象和商户服务
    config = create_config()
    merchant_service = MerchantService(config)
    
    # 创建申请单作废请求
    request = MerchantOrderCancelRequest()
    request.set_apply_id(apply_id)
    
    # 发送请求
    response = send_request_and_handle_response(merchant_service, request, "申请单作废")
    
    # 处理响应
    if response and response.is_success():
        logger.info("申请单作废成功")
    
    logger.info("申请单作废示例执行完毕")
    return response


if __name__ == "__main__":
    logger.info("=" * 50)
    logger.info("===== 商户申请单操作示例 开始 =====")
    logger.info("=" * 50)
    
    # 示例申请单号，实际使用时应替换为有效的申请单号
    apply_id = "1vzougr30f9vcw67051905ace247ef"
    
    # 先查询申请单状态
    query_response = merchant_order_query_demo(apply_id)
    
    # 如果申请单状态为待审核或审核驳回，则可以作废申请单
    if query_response and hasattr(query_response, 'audit_status'):
        if query_response.audit_status in [AUDIT_STATUS_PENDING, AUDIT_STATUS_REJECTED]:
            logger.info("\n" + "=" * 50)
            logger.info("===== 申请单作废示例 开始 =====")
            logger.info("=" * 50)
            merchant_order_cancel_demo(apply_id)
        else:
            logger.info(f"当前申请单状态为 {query_response.audit_status}，不可作废")
    
    logger.info("\n" + "=" * 50)
    logger.info("===== 所有示例执行完毕 =====")
    logger.info("=" * 50) 